package brainbots.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import brainbots.InteractiveSimulator;
import brainbots.MatrixBrainBreeder;
import brainbots.World;
import brainbots.bot.BrainBot;
import brainbots.brains.ManuallyControlledBrain;
import brainbots.brains.MatrixBrain;


public class BotFrame extends JFrame {
	
	private BotsVp viewport;
	private BotsView view;
	//private BotDocument document;
	private World world;
	private InteractiveSimulator simulator;
	private BotControl controller;
	
	private HashMap<String, Action> actions = new HashMap<String, Action>();
	private Thread redrawThread;
	private JTextField fldDelay;
	
	public BotFrame(){
		super("Bots");
		
		createActions();

		createInterface();
		createMenus();
		
		setSize(new Dimension(600,800));
		
		
		createSimulator();
	}
	
	private void createActions() {
		Action actn;
		
		actions.put("quit", new AbstractAction("Quit"){
			@Override
			public void actionPerformed(ActionEvent e) {
				BotFrame.this.setVisible(false);
			}
		});
		
		actions.put("pause", new AbstractAction("Pause"){
			@Override
			public void actionPerformed(ActionEvent e) {
				doPause();
			}
		});
		
		actions.put("play", new AbstractAction("PLay"){
			@Override
			public void actionPerformed(ActionEvent e) {
				doPlay();
			}

		});

		actions.put("set delay", new AbstractAction("Set delay"){
			@Override
			public void actionPerformed(ActionEvent e) {
				doSetDelay();
			}

		});

		
		actions.put("Default", new AbstractAction(){
			@Override
			public void actionPerformed(ActionEvent e) {
			}
		});
		
	}
	protected void doSetDelay() {
		try{
			if (simulator != null){
				simulator.setDelay(
						Integer.parseInt(fldDelay.getText())
				);
			}
		}catch (NumberFormatException e){
			JOptionPane.showMessageDialog(this, e.getMessage());
		}
		
	}

	private void doPlay() {
		if (simulator!= null)
			simulator.setPause(false);
	}

	protected void doPause() {
		if (simulator!= null)
			simulator.setPause(true);
	}

	private void createMenus() {
		// TODO Auto-generated method stub
		JMenuBar mainMenu = new JMenuBar();
	}

	private void createInterface(){
		Container c = getContentPane();
		
		JToolBar toolbar = new JToolBar();
		toolbar.add(new JButton(actions.get("pause")));
		toolbar.add(new JButton(actions.get("play")));
		c.add(toolbar, BorderLayout.NORTH);
		
		
		fldDelay = new JTextField("0");
		fldDelay.setAction(actions.get("set delay"));
		toolbar.add(new JLabel("Delay:"));
		toolbar.add(fldDelay);
		toolbar.add(new JButton(actions.get("set delay")));
		
		
		viewport = new BotsVp();
		view = new BotsView();
		viewport.setView(view);

		controller= new BotControl();
		controller.setView(view);
		viewport.addMouseListener(controller);
		viewport.addKeyListener(controller);

		
		
		c.add(viewport, BorderLayout.CENTER);
		
		createRedrawThread();
	}
	
	/**Attach a document to the view and controller*/
	private void setWorld(World w){

		simulator.setPause(true);
		this.world = w;
		simulator.setWorld(w);
		
		view.setWorld(w);

		controller.setModel(world);
		
	}
	public static void main(String[] args) {
		
		BotFrame mainFrm = new BotFrame();
		
		
		mainFrm.setWorld(mainFrm.newRandomWorld());//create rnadom document and put it into the window
		
		mainFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrm.setVisible(true);
	}
	
	private World newRandomWorld(){
        
		World world = new World();
        //add breeder
        MatrixBrainBreeder breeder = new MatrixBrainBreeder();
        world.setBreeder(breeder);
        return world;

	}
	private void createSimulator(){
		//create and set up simulator
        InteractiveSimulator sim = new InteractiveSimulator();

        sim.setDelay(0);
        sim.setDt(0.1);
        
        
        //create thread
        Thread simulatorThread = new Thread(sim,"Simulation thread");
        simulatorThread.setDaemon(true);
        simulatorThread.start();

        simulator = sim;
        
	}

	private void createRedrawThread(){
		final Runnable redraw = new Runnable(){
			@Override
			public void run() {
				if (viewport.isDisplayable())
					viewport.repaint();
			}
			
		};
		redrawThread = new Thread(new Runnable(){
			@Override
			public void run() {
				while (true){
					try {
						SwingUtilities.invokeAndWait(redraw);
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			}}, "Redraw");
		redrawThread.setDaemon(true);
		redrawThread.start();
		
	}

}
